﻿using AiProjectCSharp.Model;
using AiProjectCSharp.UI;
using AiProjectCSharp.Config;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Web;
using Sunny.UI;
using NLog;

namespace AiProjectCSharp
{
    public partial class MainWindow : Form
    {
        private FlowLayoutPanel _flowLayoutPanel;
        private Dictionary<string, UIButton> _detectButtons = new Dictionary<string, UIButton>();

        //日志
        private static Logger _logger = NLog.LogManager.GetCurrentClassLogger();
        public MainWindow()
        {
            this.StartPosition = FormStartPosition.CenterScreen;
            this.WindowState = FormWindowState.Maximized;
            InitializeComponent();
        }

        private void 客服微信ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            frmAbout f = new frmAbout();
            f.Show();

        }

        private void MainWindow_Load(object sender, EventArgs e)
        {
            // 创建FlowLayoutPanel用于动态放置按钮
            _flowLayoutPanel = new FlowLayoutPanel
            {
                Location = new Point(140, 153),
                Size = new Size(1100, 300),
                AutoScroll = true,
                FlowDirection = FlowDirection.TopDown,
                WrapContents = true,
                Margin = new Padding(5)
            };
            Controls.Add(_flowLayoutPanel);
            
            // 隐藏静态按钮，使用动态生成的按钮
            btn_DetectFire.Visible = false;
            btnGarbageDetect.Visible = false;
            btnFaceMak.Visible = false;
            
            // 添加重新加载配置按钮到菜单
            var reloadConfigMenuItem = new ToolStripMenuItem("重新加载配置");
            reloadConfigMenuItem.Click += ReloadConfigMenuItem_Click;
            关于ToolStripMenuItem.DropDownItems.Insert(0, reloadConfigMenuItem);
            
            // 加载并显示检测类型按钮
            LoadDetectButtons();
        }


        #region 火灾检测
        /// <summary>
        /// 火灾检测
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btn_DetectFire_Click(object sender, EventArgs e)
        {
            try
            {
                // 保留原有按钮的事件处理，但设置为不可见
                await RunDetectionAsync("001fire", DetectStaticEnum.火灾检测001fire, "火灾检测");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        #endregion

        #region 人脸图片检测
        /// <summary>
        /// 人脸检测
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btnFaceMak_Click(object sender, EventArgs e)
        {
            // 保留原有按钮的事件处理，但设置为不可见
            await RunDetectionAsync("003faceDetect", DetectStaticEnum.人脸检测003faceDetect, "人脸检测");
        }
        #endregion

        /// <summary>
        /// 写入日志
        /// </summary>
        /// <param name="msg"></param>
        private void WriteLogs(string msg)
        {
            uiRichTextBox_logs.Text += $"【{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}】" + msg + "\r\n";
            uiRichTextBox_logs.SelectionStart = uiRichTextBox_logs.Text.Length;
            _logger.Info(msg);
        }

        #region 垃圾检测
        /// <summary>
        /// 垃圾检测
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btnGarbageDetect_Click(object sender, EventArgs e)
        {
            // 保留原有按钮的事件处理，但设置为不可见
            await RunDetectionAsync("002garbage", DetectStaticEnum.垃圾检测002garbage, "垃圾检测");
        }

        /// <summary>
        /// 加载检测类型按钮
        /// </summary>
        private void LoadDetectButtons()
        {
            _flowLayoutPanel.Controls.Clear();
            _detectButtons.Clear();

            var detectTypes = DetectConfigManager.Instance.DetectTypes;
            
            foreach (var kvp in detectTypes)
            {
                string typeCode = kvp.Key;
                string typeName = kvp.Value;

                var button = new UIButton
                {
                    Text = $"{typeCode}{typeName}",
                    Size = new Size(375, 41),
                    Font = new Font("宋体", 12F, FontStyle.Regular),
                    Cursor = Cursors.Hand,
                    Margin = new Padding(5)
                };

                button.Click += async (sender, e) => 
                {
                    await RunDetectionAsync(typeCode, typeName, typeName);
                };

                _flowLayoutPanel.Controls.Add(button);
                _detectButtons[typeCode] = button;
            }

            // 记录日志
            AppendLog($"成功加载 {detectTypes.Count} 个检测类型");
        }

        /// <summary>
        /// 重新加载配置菜单项点击事件
        /// </summary>
        private void ReloadConfigMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                DetectConfigManager.Instance.ReloadConfig();
                LoadDetectButtons();
                AppendLog("配置重新加载成功");
                UIMessageBox.Show("配置重新加载成功！");
            }
            catch (Exception ex)
            {
                AppendLog($"配置重新加载失败: {ex.Message}");
                UIMessageBox.ShowError("配置重新加载失败，请检查配置文件格式！");
            }
        }
        #endregion

        #region 通用检测方法
        /// <summary>
        /// 通用检测方法
        /// </summary>
        /// <param name="modelCode">模型编码</param>
        /// <param name="detectType">检测类型枚举</param>
        /// <param name="detectionName">检测名称（用于日志显示）</param>
        private async Task RunDetectionAsync(string modelCode, string detectType, string detectionName)
        {
            AppendLog($"开始{detectType}检测...");
            try
            {
                // 打开文件选择器，获取文件路径
                OpenFileDialog openFileDialog = new OpenFileDialog();
                openFileDialog.Filter = "图片文件|*.jpg;*.png;*.jpeg;*.bmp";
                openFileDialog.InitialDirectory = Application.StartupPath + "\\TestImg";
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    // 获取文件路径
                    string sourceImagePath = openFileDialog.FileName;
                    AppendLog($"正在上传图片进行{detectionName}: {sourceImagePath}，请稍后！");

                    // 显示等待提示
                    this.Cursor = Cursors.WaitCursor;
                    
                    // 禁用所有检测按钮
                    foreach (Control control in this.Controls)
                    {
                        if (control is Button && control.Name.StartsWith("btn"))
                        {
                            control.Enabled = false;
                        }
                    }

                    try
                    {
                        // 调用API进行检测
                        var detectionResult = await UploadImageForDetectionAsync(sourceImagePath, modelCode, detectionName);

                        if (detectionResult != null)
                        {
                            // 获取检测结果
                            string resultJson = detectionResult.Item1; // JSON字符串
                            string resultImagePath = detectionResult.Item2; // 检测后的图片本地路径

                            AppendLog($"【{detectionName}结果】检测完成，找到目标数量: {CountDetections(resultJson)}");
                            
                            // 显示结果
                            frmDetectImg frmDetectImg = new frmDetectImg(sourceImagePath, resultImagePath, detectType, resultJson);
                            frmDetectImg.Show();
                        }
                        else
                        {
                            AppendLog($"【{detectionName}结果】检测失败，未获得有效结果");
                            MessageBox.Show("检测失败，请检查网络连接或API服务是否正常。");
                        }
                    }
                    finally
                    {
                        // 恢复界面状态
                        this.Cursor = Cursors.Default;
                        
                        // 启用所有检测按钮
                        foreach (Control control in this.Controls)
                        {
                            if (control is Button && control.Name.StartsWith("btn"))
                            {
                                control.Enabled = true;
                            }
                        }
                        
                        // 自动滚动到日志最后
                        uiRichTextBox_logs.SelectionStart = uiRichTextBox_logs.Text.Length;
                        uiRichTextBox_logs.ScrollToCaret();
                    }
                }
            }
            catch (Exception ex)
            {
                this.Cursor = Cursors.Default;
                
                // 启用所有检测按钮
                foreach (Control control in this.Controls)
                {
                    if (control is Button && control.Name.StartsWith("btn"))
                    {
                        control.Enabled = true;
                    }
                }
                
                AppendLog($"【{detectionName}错误】{ex.Message}");
                
                // 自动滚动到日志最后
                uiRichTextBox_logs.SelectionStart = uiRichTextBox_logs.Text.Length;
                uiRichTextBox_logs.ScrollToCaret();
                
                MessageBox.Show($"检测过程中发生错误: {ex.Message}");
            }
        }

        /// <summary>
        /// 添加日志
        /// </summary>
        /// <param name="msg"></param>
        private void AppendLog(string msg)
        {
            WriteLogs(msg);
        }
        #endregion

        #region API调用相关方法
        /// <summary>
        /// 上传图片到AI检测接口并获取检测结果
        /// </summary>
        /// <param name="imagePath">图片文件路径</param>
        /// <param name="modelCode">模型编码</param>
        /// <returns>返回元组：(JSON结果字符串, 本地保存的检测结果图片路径)</returns>
        private async Task<Tuple<string, string>> UploadImageForDetectionAsync(string imagePath, string modelCode, string detectionName)
        {
            try
            {
                modelCode = modelCode.ToLower();//转换为小写，避免模型编码大小写不匹配

                // API接口地址
                string apiUrl = "http://14.103.236.44:18001/api/ai/detect";
                
                // 检查图片文件是否存在
                if (!System.IO.File.Exists(imagePath))
                {
                    AppendLog($"错误: 图片文件不存在 - {imagePath}");
                    return null;
                }
                
                AppendLog($"正在上传图片: {imagePath}");
                AppendLog($"{detectionName}检测请求API: {apiUrl}");
                AppendLog($"使用模型编码: {modelCode}");
                
                using (var httpClient = new System.Net.Http.HttpClient())
                using (var formData = new System.Net.Http.MultipartFormDataContent())
                {
                    // 添加模型编码字段
                    formData.Add(new System.Net.Http.StringContent(modelCode), "model_code");
                    
                    // 读取图片文件并添加到表单
                    byte[] imageData = System.IO.File.ReadAllBytes(imagePath);
                    var imageContent = new System.Net.Http.ByteArrayContent(imageData);
                    imageContent.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("image/jpeg");
                    formData.Add(imageContent, "file", System.IO.Path.GetFileName(imagePath));
                    
                    // 发送请求
                    var response = await httpClient.PostAsync(apiUrl, formData);
                    
                    // 检查响应状态
                    response.EnsureSuccessStatusCode();
                    
                    // 读取响应内容
                    string responseContent = await response.Content.ReadAsStringAsync();
                    
                    // 解析JSON响应
                    var jsonResult = JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(responseContent);
                    
                    // 获取检测结果图片URL
                    string detectedUrl = jsonResult["detected_url"].ToString();
                    
                    // 下载检测结果图片到本地
                    string localDetectedPath = await DownloadDetectedImageAsync(detectedUrl, imagePath);
                    
                    return new Tuple<string, string>(responseContent, localDetectedPath);
                }
            }
            catch (System.Net.Http.HttpRequestException ex)
            {
                AppendLog($"HTTP请求错误: {ex.Message}");
                throw;
            }
            catch (Exception ex)
            {
                AppendLog($"发生错误: {ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 下载检测结果图片到本地
        /// </summary>
        /// <param name="imageUrl">图片URL</param>
        /// <param name="originalImagePath">原始图片路径</param>
        /// <returns>本地保存的图片路径</returns>
        private async Task<string> DownloadDetectedImageAsync(string imageUrl, string originalImagePath)
        {
            try
            {
                // 创建保存目录
                string outputDir = System.IO.Path.Combine(Application.StartupPath, "detect_out");
                if (!System.IO.Directory.Exists(outputDir))
                {
                    System.IO.Directory.CreateDirectory(outputDir);
                }
                
                // 生成保存文件名，基于模型编码
                string modelCode = "default"; // 默认为default
                
                // 从URL中提取模型编码
                if (!string.IsNullOrEmpty(imageUrl))
                {
                    try
                    {
                        // 尝试从URL中解析模型编码
                        Uri uri = new Uri(imageUrl);
                        string query = uri.Query;
                        if (!string.IsNullOrEmpty(query))
                        {
                            // 简单解析query string中的model_code参数
                            var queryParams = System.Web.HttpUtility.ParseQueryString(query);
                            if (!string.IsNullOrEmpty(queryParams["model_code"]))
                            {
                                modelCode = queryParams["model_code"];
                            }
                        }
                    }
                    catch { }
                }
                
                string fileName = $"detected_{System.IO.Path.GetFileNameWithoutExtension(originalImagePath)}_{modelCode}.jpg";
                string savePath = System.IO.Path.Combine(outputDir, fileName);
                
                // 下载图片
                using (var httpClient = new System.Net.Http.HttpClient())
                {
                    byte[] imageBytes = await httpClient.GetByteArrayAsync(imageUrl);
                    System.IO.File.WriteAllBytes(savePath, imageBytes);
                }
                
                AppendLog($"检测结果图片已保存到: {savePath}");
                return savePath;
            }
            catch (Exception ex)
            {
                AppendLog($"下载图片失败: {ex.Message}");
                // 如果下载失败，返回原始图片路径作为备选
                return originalImagePath;
            }
        }

        /// <summary>
        /// 统计检测到的目标数量
        /// </summary>
        /// <param name="jsonResult">JSON结果字符串</param>
        /// <returns>目标数量</returns>
        private int CountDetections(string jsonResult)
        {
            try
            {
                var result = Newtonsoft.Json.JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(jsonResult);
                var detections = result["detections"] as Newtonsoft.Json.Linq.JArray;
                return detections?.Count ?? 0;
            }
            catch
            {
                return 0;
            }
        }
        #endregion
    }
}
